<?php
/**
 * @link https://www.kancloud.cn/cleverstone/ymb2
 * @copyright Copyright (c) 2020 Yii Manager Software LLC
 */

namespace builder\helper;

use Yii;
use yii\bootstrap4\Alert;
use yii\helpers\ArrayHelper;
use yii\helpers\Html;
use yii\helpers\Json;

/**
 * HTML5
 * @author cleverstone
 * @since ym2.0
 * @example
 * ```html
 * //a标签
 * <a target="_blank"></a> //打开新标签页
 * <a target="_self"></a>  //当前窗口打开
 * <a target="_parent"></a>//父窗口打开，无父窗口和_self一样
 * <a target="_top"></a>   //顶级窗口打开，无父窗口和_self一样
 * <a target="_open"></a>  //新窗口打开
 * ```
 */
class H5 extends Html
{
    // 表格单元格分割线
    const TABLE_CELL_DIVISION = "\n<hr style='margin:6px -15px;border-top-style:dashed;'/>\n";

    /**
     * 注册后台元数据标签
     * @return string
     */
    public static function registerBackendMetaTags(): string
    {
        $themeColor = Yii::$app->view->params['themeColor'];

        return static::tag('meta', '', ['name' => 'http-success-code', 'content' => App::params('http.res.success')]) . "\n"
            . static::tag('meta', '', ['name' => 'http-failure-code', 'content' => App::params('http.res.failure')]) . "\n"
            . static::tag('meta', '', ['name' => 'http-unauthorized-code', 'content' => App::params('http.res.unauthorized')]) . "\n"
            . static::tag('meta', '', ['name' => 'http-ajax-identity', 'content' => App::params('http.ajax.identity')]) . "\n"
            . static::tag('meta', '', ['name' => 'admin-route-login', 'content' => Url::to(App::params('admin.route.login'), '')]) . "\n"
            . static::tag('meta', '', ['name' => 'app-theme-color', 'content' => $themeColor]) . "\n";
    }

    /**
     * 注册增强型Web App清单
     * @return string
     */
    public static function registerPWA_Manifest(): string
    {
        $webPath = Yii::getAlias('@webroot');

        $htmlTags = '';
        if (is_file($webPath . '/manifest.json')) {
            // Windows Os
            $htmlTags .= static::tag('link', '', ['rel' => 'manifest', 'href' => '/manifest.json']) . "\n";
        }

        if (is_file($webPath . '/manifest.webmanifest')) {
            // Mac Os
            $htmlTags .= static::tag('link', '', ['rel' => 'manifest', 'href' => '/manifest.webmanifest']) . "\n";
        }

        return $htmlTags;
    }

    /**
     * alert组件
     *
     * @param string $message 消息内容
     * @param string $type alert类型
     * - normal 无
     * - info 信息
     * - error 错误
     * - danger 危险
     * - success 成功
     * - warning 警告
     * @param array|false $closeButton 关闭按钮
     * @param array $options 标签选项
     * @param bool $nl2br 回车是否转br标签
     * @return string
     */
    public static function alert($message, $type = 'normal', $closeButton = [], array $options = [], $nl2br = true)
    {
        $typeDefinition = ['normal' => 'alert-normal', 'error'   => 'alert-danger', 'danger'  => 'alert-danger', 'success' => 'alert-success', 'info'    => 'alert-info', 'warning' => 'alert-warning'];
        $alert = ['f13', 'line-height22'];

        if ($type && !empty($typeDefinition[$type])) {
            $alert[] = $typeDefinition[$type];
        }

        self::addCssClass($options, ['layout' => implode(' ', $alert)]);

        return Alert::widget([
            'body' => preg_replace('/`(.*?)`/', '<span class="ym2-text-code" style="font-size: .92em;">\\1</span>', $nl2br ? nl2br($message) : $message),
            'closeButton' => $closeButton,
            'options' => $options,
        ]);
    }

    /**
     * 扩展img标签助手方法
     * @param string $src 图片路径
     * @param array $options 选项
     * @return string
     */
    public static function img($src, $options = [])
    {
        if (empty($src)) return '';
        return parent::img(Url::attachmentUrl($src), $options);
    }

    /**
     * 生成自适应高度的图片
     * @param string $src 图片路径
     * @param int|string $width 图宽
     * @param int|string $height 图高
     * @param array $options 额外选项
     * @return string
     */
    public static function imgX($src, $width, $height, array $options = [])
    {
        if (empty($src)) return '';
        if (is_numeric($width)) $width .= 'px';
        if (is_numeric($height)) $height .= 'px';

        //img
        $imageOption = ArrayHelper::remove($options, 'image', []);
        self::addCssStyle($imageOption, ['width' => $width], false);
        $imageOption['ym2-full-image'] = '';
        $img = self::img($src, $imageOption);

        //img container
        self::addCssClass($options, ['widget' => 'img-flex-style']);
        self::addCssStyle($options, ['width' => $width, 'height' => $height]);

        return Html::tag('div', $img, $options);
    }

    /**
     * 徽章标签
     * @param string $content 标签内容
     * @param string $color 徽章颜色
     * - primary    主题颜色
     * - pink       粉
     * - red        红
     * - orange     橙
     * - warning    黄
     * - green      绿
     * - success    深绿
     * - cyan       青
     * - blue       蓝
     * - purple     紫
     * - light      浅色
     * - gray       灰
     * - gray1      灰(二级)
     * - secondary  深灰
     * - black      黑
     * @param string $appearance 徽章外观
     * - layui-badge-dot 点
     * - layui-badge     矩形
     * @param array $options 标签选项
     * @return string
     */
    public static function badge($content, $color = 'primary', $appearance = 'layui-badge', $options = [])
    {
        if ($content === '' || $content === null) {
            return '';
        }

        self::addCssClass($options, [$appearance, "layui-bg-{$color}"]);
        return self::tag('span', $content, $options);
    }

    /**
     * 徽章标签(点)
     * @param string|null $content 文本内容
     * @param string $color 点主题颜色
     * @param boolean $dotPositionLeft 点排序位置
     * @param array $badgeDotOptions 点徽章选项
     * @param array $textOptions 文本选项
     * @return string
     * @see badge()
     */
    public static function badgeDot($content, $color = 'primary', $dotPositionLeft = true, $badgeDotOptions = [], $textOptions = [])
    {
        $result = [];
        $result[] = self::badge(' ', $color, 'layui-badge-dot', $badgeDotOptions);
        if ($content !== '' && $content !== null) {
            self::addCssClass($textOptions, ['pl-2']);
            $result[] = self::tag('text', $content, $textOptions);
        }

        if (true !== $dotPositionLeft) {
            $result = array_reverse($result);
        }

        return self::tag('span', implode("\n", $result), ['class' => 'd-flex flex-row align-items-center']);
    }

    /**
     * h5文本
     * @param string $content 文本
     * @param array $options 选项
     * @param string $tag 标签
     * @return string
     */
    public static function text($content, $options = [], $tag = 'span')
    {
        return self::tag($tag, $content, $options);
    }

    /**
     * 生成layui主题的面包屑导航
     * @return null|string
     * ```php
     * * App::setViewBreadcrumb([
     * *      ['name' => '首页'],
     * *      ['name' => '积分列表','url' => 'admin/integral'],
     * *      ['name' => '新增积分'],
     * * ])
     * * ```
     * @see App::setViewBreadcrumb()
     */
    public static function getViewBreadcrumb()
    {
        $viewParams = Yii::$app->view->params;
        if (!empty($viewParams['breadcrumb'])) {
            $breadcrumb = $viewParams['breadcrumb'];
            $content = [];
            foreach ($breadcrumb as $item) {
                if (!empty($item['url'])) {
                    $content[] = Html::a($item['name'], Url::to($item['url'], ''));
                } else {
                    $content[] = "<a><cite>{$item['name']}</cite></a>";
                }
            }

            return Html::tag('span', implode("\n", $content), ['class' => 'layui-breadcrumb']);
        }

        return null;
    }

    /**
     * 语法高亮(静态渲染)
     * ```注意：请先注册动态插件`highlight`
     * App::registerDynamicAsset(['highlight'], function () {
     *      //注册高亮web插件，并且初始化语言项和主题。下面注释部分是默认值！
     *      //\builder\bundle\Highlight::$supportLangs = ['php', 'json'];
     *      //\builder\bundle\Highlight::$curTheme = 'idea';
     *      //\builder\bundle\Highlight::$isAutoHighlightAll = true;
     * });
     * ```
     * @param string $codes 需要高亮的代码内容
     * @param string $lang 指定编程语言
     * @param array $preTagOptions HTML <pre>标签选项
     * @return string
     */
    public static function highlightGrammar($codes, $lang = 'php', $preTagOptions = [])
    {
        $codeTag = H5::tag('code', self::encode($codes), ['class' => 'h-100 language-' . $lang]);
        return H5::tag('pre', $codeTag, $preTagOptions);
    }

    /**
     * Layui评分组件
     *
     * Example：
     * ```php
     * H5::layuiStar([
     *      'value' => 5,
     *      'readonly' => true,
     * ]);
     * ```
     * @param array $options 选项
     * @return string
     * @see https://layui.dev/docs/2/rate/#options
     */
    public static function layuiStar($options)
    {
        return H5::tag('div', '', [
            'ngx-layuistar' => '',
            'lay-options' => Json::encode($options),
        ]);
    }

    /**
     * 渲染加载动画
     * @return string
     */
    public static function renderSpinner()
    {
        return <<<'HTML'
<div class="ui-spindot">
    <div class="ui-spin ui-spin-spinning ui-spin-md">
        <span class="ui-spin-dot ui-spin-dot-spin">
            <i class="ui-spin-dot-item"></i>
            <i class="ui-spin-dot-item"></i>
            <i class="ui-spin-dot-item"></i>
            <i class="ui-spin-dot-item"></i>
        </span>
    </div>
</div>
HTML;
    }

    /**
     * 内容复制按钮
     * @param string $clipboardContent 要复制的内容
     * @param string $btnTitle 按钮标题
     * @param array $options 标签选项
     * @return string
     */
    public static function duplicateButton(string $clipboardContent, string $btnTitle = '复制', array $options = []): string
    {
        return H5::a($btnTitle, 'javascript:;', array_merge($options, ['ym2-clipboard' => $clipboardContent]));
    }

    /**
     * 表单input控件前缀或后缀按钮
     * ```php
     * WidgetFacade::echo2Return(function () {
     *      BlockModal::begin([
     *           'url' => 'user/create',
     *           'closeCallback' => 'console.log("This is modal-close callback. ")',
     *           'scope' => [
     *                'p1' => 'default1[\'Field1\']',
     *                'p2' => 'default1[\'Field2\']',
     *           ],
     *      ]);
     *      echo H5::buttonSuffix('打开');
     *      BlockModal::end();
     * });
     *
     * ```
     * @param string $btnName
     * @param array $options
     * @return string
     */
    public static function buttonSuffix($btnName, $options = [])
    {
        self::addCssClass($options, ['default' => 'layui-btn layui-btn-sm layui-btn-primary']);
        self::addCssStyle($options, 'margin-left: -1px; margin-right: -1px', false);

        return self::button($btnName, $options);
    }

    /**
     * 打印按钮
     *
     * @param string $btnName
     * @param array $options
     * @return string
     */
    public static function printButton($btnName = '打 印', $options = [])
    {
        if (empty($options['type'])) {
            $options['type'] = 'print';
        }

        self::addCssClass($options, ['default' => 'layui-btn layui-btn-primary']);
        return self::button($btnName, $options);
    }
}